package AIEngine;

/**
 * The AIPlayer class implements all methods that are used 
 * to assess the next move.
 *
 * @see Player#request( Move opponentMove )
 * @see Player#confirm( Status boardStatus )
 */
import GameEngine.*;

/**
 *
 * @author S.Herzog
 */
@SuppressWarnings("unused")
public class AIPlayer implements Player {

    Board board = new Board();
    int[] rot = new int[2];
    /**
     *
     */
    public int[][] basic = {
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0}};
    /**
     *
     */
    public int[][] tmpBoard = new int[6][6];
    private boolean black;
    private String color;
    private Move lastMove = null;

    /**
     * The default constructor for a aiplayer
     *
     * @param black shows if the player is first or second
     */
    public AIPlayer(boolean black) {
        this.black = black;
        this.color = this.black ? "black" : "red";
        System.out.println("Player " + this.color + " comes up!");

    }
    /**
     * This method handles the interaction between the
     * player and the playing field.
     *
     * @param opponentMove The last move of the opponent player.
     * @return Returns An object that represents the current move.
     */
    public Move request(Move opponentMove, int turnsLeft) throws Exception{

        int mov[] = {-1, -1, 1, 1};
        Move move = null;
        boolean clockwise;

        if (opponentMove != null) {
            System.out.println("Got opponent move (" + opponentMove + "). ");
            if (board.getStatus().value() == 0) {
                System.out.println("Opponent move:");
                setter(opponentMove, false);
            }
        }

        AlphaBetaEngine test = new AlphaBetaEngine(black); // Run AlphaBetaEngine
        //MinMaxEngine test = new MinMaxEngine(black);
        tmpBoard = basic.clone();
        Node parent = new Node(null, basic, turnsLeft);
        parent.setCamp(black);



        if (test.getBestMove(parent).getValue() > 0) { //If board Value bigger then zero use the alphabeta engine

            clockwise = (test.getBestMove(parent).getMove()[3] > 0) ? true : false;
            move = new GameEngine.Move(this.black, test.getBestMove(parent).getMove()[1] + 1, test.getBestMove(parent).getMove()[0] + 1, test.getBestMove(parent).getMove()[2], clockwise);


        } else {

            tmpBoard = basic.clone();
            BasicAI.fullJudge(tmpBoard, black);
            rot = BasicAI.searchBestRotation(tmpBoard, black);
            mov[0] = BasicAI.getMaxValueCoord(tmpBoard, black)[0];
            mov[1] = BasicAI.getMaxValueCoord(tmpBoard, black)[1];
            mov[2] = rot[0];
            mov[3] = rot[1];
            clockwise = (mov[3] > 0) ? true : false;

            move = new GameEngine.Move(this.black, mov[1] + 1, mov[0] + 1, mov[2], clockwise);
        }




        if (board.getStatus().value() == 0) {
            System.out.println("Your move:");
            setter(move, true);
        }
        this.lastMove = move;
        return move;
    }

    /**
     * Checks if an error occured or if an move was illegal.
     *
     * @param boardStatus Information of the last move.
     */
    public void confirm(Status boardStatus) throws Exception{

        if (boardStatus.value() == Status.ILLEGAL_MOVE) {       // checks if last move is valid
            throw new Exception("Illegal move!");
        }

        if (boardStatus.value() == Status.ERROR) {             //checks if an error occurred
            throw new Exception("Error occurred!");
        }
        if (boardStatus.value() == Status.BLACK_WINS) {         // checks if black wins
            System.out.println("Black (@) wins!");

        }
        if (boardStatus.value() == Status.RED_WINS) {         // checks if red wins
            System.out.println("Red (#) wins!");
        }
        if (boardStatus.value() == Status.DRAW) {           // checks if a draw occurres
            System.out.println("Draw!");
        }
    }

    /**
     * The setter is supposed to set every move his own aiboard.
     *
     * @param move Moveobjekt conatains the colum, row, quadrant and the direction of rotation
     * @param black represents the playerside
     */
    public void setter(Move move, boolean black) {
        int ver, hor, quad;
        ver = move.column();
        hor = move.row();
        quad = move.element();
        board.setMarble(ver, hor, move.black());
        board.rotate(quad, move.clockwise());
        this.basic = board.getBoard();

    }
}

